package com.ruoyi.framework.security.filter;

import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.concurrent.TimeUnit;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.ServletUtils;
import com.ruoyi.common.utils.ip.IpUtils;
import com.ruoyi.common.utils.status.ResponseUtil;
import com.ruoyi.xqsp.domain.SpUsers;
import com.ruoyi.xqsp.domain.UrlFilter;
import com.ruoyi.xqsp.service.UrlFilterService;
import com.ruoyi.xqsp.utils.TokenServices;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.WebAuthenticationDetailsSource;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.filter.OncePerRequestFilter;
import com.ruoyi.common.core.domain.model.LoginUser;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.framework.web.service.TokenService;

/**
 * token过滤器 验证token有效性
 *
 * @author ruoyi
 */
@Component
@Log4j2
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter
{
    @Autowired
    private TokenServices tokenService;

    @Autowired
    RedisTemplate redisTemplate;

    @Autowired
    UrlFilterService urlFilterService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
            throws ServletException, IOException
    {

        ArrayList<String> list = new ArrayList<>();
        list.add("/xqsp/advertising/getAll");
        list.add("/xqsp/callback/zhifuFM");

        //限制请求时间
        ArrayList<String> lists = new ArrayList<>();
        lists.add("/xqsp/history/addHistory");
        lists.add("/xqsp/comic/buyComics");



        SpUsers loginUser = tokenService.getLoginUser(request);
        ParameterRequestWrapper requestWrapper = new ParameterRequestWrapper((HttpServletRequest)request);
        String token = requestWrapper.getHeader("Authorization");
        requestWrapper.addParameter("userId",StringUtils.isNotNull(loginUser)?loginUser.getUserId():null);
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
        String format = LocalDateTime.now().format(dateTimeFormatter);
        String ip = IpUtils.getIpAddr(requestWrapper);

        UrlFilter urlFilter = new UrlFilter();
        urlFilter.setToken(token);
        urlFilter.setUrlPath(requestWrapper.getRequestURI());
        urlFilter.setIp(ip);
        urlFilter.setTime(format);
        urlFilterService.save(urlFilter);
        log.info("请求地址{} 请求时间{}" ,requestWrapper.getRequestURI(), format);
        if (StringUtils.isNotNull(loginUser) && StringUtils.isNull(SecurityUtils.getAuthentication()))
        {
            if (list.contains(requestWrapper.getRequestURI())){
                Object obj = redisTemplate.opsForValue().get("stint:" + token);
                if (obj != null){
//                    redisTemplate.opsForValue().set("stint:"+token,1,1, TimeUnit.SECONDS);
                    ServletUtils.renderString(response, JSON.toJSONString(ResponseUtil.fail(401, "请求过快")));
                    return;
                }else {
                    redisTemplate.opsForValue().set("stint:"+token,1,1, TimeUnit.SECONDS);
                }

            }

            tokenService.refreshToken(loginUser);
            UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(loginUser, null, null);
            authenticationToken.setDetails(new WebAuthenticationDetailsSource().buildDetails(requestWrapper));
            SecurityContextHolder.getContext().setAuthentication(authenticationToken);
        }else {


//            if (token != null && ! "".equals(token)){
////                throw new BadCredentialsException("token过期");
//                if (! list.contains(requestWrapper.getRequestURI())) {
//                    ServletUtils.renderString(response, JSON.toJSONString(ResponseUtil.fail(5003, "登录失效,请重新登录")));
//                    return;
//                }
//            }
        }

        chain.doFilter(requestWrapper, response);
    }
}
